<template>
    <button
        class="a-button"
        :disabled="disabled"
        :class="[
            `color-${color}`,
            `size-${size}`,
            { disabled: disabled },
            { sharp: sharp },
            { 'c-circle': circle },
            square || circle ? `c-square-${size}` : '',
            { 'c-w-100': block },
            { loading: myLoading },
            { plain: plain },
            { link: link },
            `c-align-${align}`,
        ]"
    >
        <span class="fa fa-fw fa-spinner fa-spin" v-if="myLoading"></span>
        <slot v-if="!(square && myLoading)"></slot>
    </button>
</template>

<style lang="scss" scoped>
@import "../scss/vars";

.a-button {
    padding: 0;
    &:not(.loading) {
        cursor: pointer;
    }
    border: none;
    outline: none;
    font-family: inherit;

    @each $colorPackageName, $colorPackageValue in $colorPackages {
        $themeColor: map-get($colorPackageValue, "themeColor");
        $frontColor: map-get($colorPackageValue, "frontColor");
        $bgColor: map-get($colorPackageValue, "bgColor");
        &.color-#{$colorPackageName} {
            &:not(.link) {
                &:not(.plain) {
                    color: $frontColor;
                    background-color: $bgColor;
                }
                &.plain {
                    color: map-get($colorPackageValue, "themeColor");
                    background-color: transparent;
                }

                &:hover:not(.disabled) {
                    color: $frontColor;
                    background-color: lighten($bgColor, 10%);
                }

                &:focus:not(.disabled) {
                    color: $frontColor;
                    background-color: lighten($bgColor, 10%);
                }

                &:active:not(.disabled) {
                    color: $frontColor;
                    background-color: darken($bgColor, 10%);
                }

                &.loading {
                    color: $frontColor;
                    background-color: lighten($bgColor, 10%);
                    pointer-events: none;
                }
            }

            &.link {
                color: $themeColor;
                background-color: transparent;

                &:hover:not(.disabled) {
                    color: lighten($themeColor, 10%);
                }

                &:focus:not(.disabled) {
                    color: lighten($themeColor, 10%);
                }

                &:active:not(.disabled) {
                    color: darken($themeColor, 10%);
                }

                &.loading {
                    color: lighten($themeColor, 10%);
                    pointer-events: none;
                }
            }

            &.disabled {
                opacity: 0.5;
                cursor: not-allowed;
            }
        }
    }

    @each $sizePackageName, $sizePackageValue in $sizePackages {
        &.size-#{$sizePackageName} {
            &:not(.c-square-#{$sizePackageName}) {
                padding-left: map-get($sizePackageValue, "space");
                padding-right: map-get($sizePackageValue, "space");
                height: map-get($sizePackageValue, "size");
            }

            font-size: map-get($sizePackageValue, "fontSize");
            &:not(.sharp):not(.c-circle) {
                border-radius: map-get($sizePackageValue, "borderRadius");
            }
        }
    }
}
</style>

<script>
export default {
    props: {
        color: {
            type: String,
            default: 'default',
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        size: {
            type: String,
            default: 'm',
        },
        sharp: {
            type: Boolean,
            default: false,
        },
        circle: {
            type: Boolean,
            default: false,
        },
        square: {
            type: Boolean,
            default: false,
        },
        block: {
            type: Boolean,
            default: false,
        },
        loading: {
            type: [Boolean, Promise],
            default: false,
        },
        plain: {
            type: Boolean,
            default: false,
        },
        link: {
            type: Boolean,
            default: false,
        },
        align: {
            type: String,
            default: 'center',
        },
    },
    data() {
        return {
            myLoading: false
        }
    },
    watch: {
        loading() {
            this.updateLoading()
        }
    },
    mounted() {
        this.updateLoading()
    },
    methods: {
        updateLoading() {
            if (this.loading instanceof Promise) {
                this.myLoading = true
                this.loading.finally(() => {
                    this.myLoading = false
                })
            } else {
                this.myLoading = this.loading
            }
        }
    }
}
</script>